package com.hejjon.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hejjon.core.bean.TableField;
import com.hejjon.core.domain.entity.SysDatabase;
import com.hejjon.core.enumer.DeleteFlagEnum;
import com.hejjon.core.exception.BusinessException;
import com.hejjon.core.utils.DateTimeUtil;
import com.hejjon.core.utils.StrUtil;
import com.hejjon.domain.bo.RunInsertSqlBO;
import com.hejjon.domain.bo.RunQuerySqlBO;
import com.hejjon.domain.bo.RunSqlBO;
import com.hejjon.domain.bo.RunUpdateSqlBO;
import com.hejjon.domain.dto.DatabaseDTO;
import com.hejjon.domain.dto.DatabaseQueryDTO;
import com.hejjon.domain.pojo.ConnectionInfo;
import com.hejjon.domain.vo.DatabaseTreeNodeVO;
import com.hejjon.domain.vo.DatabaseVO;
import com.hejjon.mapper.SysDatabaseMapper;
import com.hejjon.service.IConnectionService;
import com.hejjon.service.ISqlBuilderService;
import com.hejjon.service.ISysDatabaseService;
import com.hejjon.util.JDBCUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: cs
 * @date: 2025-02-24 11:05:29
 * @since: 1.0
 */
@Service
public class SysDatabaseServiceImpl extends ServiceImpl<SysDatabaseMapper, SysDatabase> implements ISysDatabaseService {

    private static final Logger log = LoggerFactory.getLogger(SysDatabaseServiceImpl.class);


    @Resource
    private SysDatabaseMapper sysDatabaseMapper;

    @Resource
    private IConnectionService connectionService;

    @Resource
    private ISqlBuilderService sqlBuilderService;

    @Override
    public List<DatabaseTreeNodeVO> findDatabaseTreeList() {
        return null;
    }

    @Override
    public boolean create(DatabaseDTO databaseDTO) {

        String connectionId = databaseDTO.getConnectionId();
        if (StringUtils.isEmpty(connectionId)) {
            throw new BusinessException("数据库连接ID不可为空!");
        }
        ConnectionInfo connInfo = ConnectionInfo.of(connectionService.getById(connectionId), true);
        Connection connection = JDBCUtil.getConnection(connInfo);
        if (databaseDTO.isDeleteExist()) {
            String dropSql = sqlBuilderService.dropIfDatabaseExists(databaseDTO.getName());
            boolean b = JDBCUtil.executeSQL(connection, dropSql);
            if (b) {
                log.info("数据库 {} 删除成功!", databaseDTO.getName());
            }
        }
        boolean res = JDBCUtil.executeSQL(connection, sqlBuilderService.createDB(databaseDTO.getName()));
        if (res) {
            SysDatabase ds = new SysDatabase();
            ds.setName(databaseDTO.getName());
            ds.setLabel(databaseDTO.getDescription());
            ds.setConnectionId(databaseDTO.getConnectionId());
            ds.setDescription(databaseDTO.getDescription());
            ds.setType(databaseDTO.getType());
            ds.setId(StrUtil.getUUID());
            ds.setEnable(1);
            ds.setDriverType(connInfo.getDriver());
            ds.setCreateBy("admin");
            ds.setCreateTime(LocalDateTime.now());
            ds.setDeleteFlag(DeleteFlagEnum.NO.getCode());
            int insert = baseMapper.insert(ds);
            return insert > 0;
        }
        return false;
    }

    @Override
    public List<DatabaseVO> findList(DatabaseQueryDTO queryDTO) {
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>> dasfasfasfasfasf");
        return sysDatabaseMapper.selectBy(queryDTO);
    }



    @Override
    public boolean remove(DatabaseDTO dto) {
        ConnectionInfo connInfo = ConnectionInfo.of(connectionService.getById(dto.getConnectionId()), true);
        Connection connection = JDBCUtil.getConnection(connInfo);
        String dbName = dto.getName();
        if (dto.isDelDb()) {
            String sql = sqlBuilderService.dropIfDatabaseExists(dbName);
            JDBCUtil.executeSQL(connection, sql);
        }
        int i = sysDatabaseMapper.update(null,new LambdaUpdateWrapper<SysDatabase>()
                .eq(SysDatabase::getDeleteFlag,DeleteFlagEnum.NO.getCode())
                .eq(SysDatabase::getId,dto.getId())
                .set(SysDatabase::getUpdateTime,LocalDateTime.now())
                .set(SysDatabase::getUpdateBy,"admin").set(SysDatabase::getDeleteFlag,DeleteFlagEnum.YES.getCode()));
        return i > 0;
    }

    @Override
    public void executeCreateTable(Connection connection, String databaseName, String createTableSQL) {
        try {
            JDBCUtil.executeSQL(connection, sqlBuilderService.useDatabase(databaseName));
            JDBCUtil.executeSQL(connection, createTableSQL);
            log.info("表创建成功!");
        } catch (Exception e) {
            log.error("表创建失败, SQL语句: {}", createTableSQL, e);
        }
    }


    @Override
    public RunSqlBO loadRunSqlBO(String databaseId) {

        SysDatabase sysDatabase = sysDatabaseMapper.selectById(databaseId);
        if (sysDatabase == null) {
            throw new BusinessException("数据库不存在, databaseId: " + databaseId);
        }
        String connectionId = sysDatabase.getConnectionId();
        ConnectionInfo connInfo = ConnectionInfo.of(connectionService.getById(connectionId), true);
        Connection connection = JDBCUtil.getConnection(connInfo);
        RunSqlBO bo = new RunSqlBO();
        bo.setDatabaseName(sysDatabase.getName());
        bo.setConnection(connection);

        return bo;
    }

    @Override
    public boolean executeDropTables(RunSqlBO runSqlBO, List<String> tableNameList) {
        tableNameList = tableNameList.stream().filter(o -> o != null && !o.isEmpty()).collect(Collectors.toList());
        if (tableNameList.isEmpty()) {
            return false;
        }
        log.info("开始删除表: {}", StringUtils.join(tableNameList, ","));
        Connection connection = runSqlBO.getConnection();
        String databaseName = runSqlBO.getDatabaseName();
        List<String> dropSqlList = sqlBuilderService.dropIfTableExists(databaseName, tableNameList);
        return JDBCUtil.batchExecuteSQL(connection, dropSqlList);
    }


    @Override
    public List<Map<String, Object>> executeQuery(RunQuerySqlBO querySqlBO) {
        return JDBCUtil.executeQuery(querySqlBO);
    }


    @Override
    public int executeInsert(RunInsertSqlBO insertSqlBO) {
        // 规范化插入的数据
        formatFieldValue(insertSqlBO.getFieldList(), insertSqlBO.getValueList());
        return JDBCUtil.executeInsert(insertSqlBO);
    }

    /**
     * 格式化字段值
     * @param fieldList 字段列表
     * @param valueList 字段值
     */
    private void formatFieldValue(List<TableField> fieldList, List<Map<String, Object>> valueList) {
        for (Map<String, Object> valueMap : valueList) {
            for (TableField field : fieldList) {
                String name = field.getName();
                Object fieldValue = valueMap.get(name);
                if (fieldValue == null) {
                    continue;
                }
                if (field.getIsDate()) {
                    fieldValue = DateTimeUtil.dateObjectFormat(fieldValue, DateTimeUtil.DATE_FORMAT);
                }
                if (field.getIsDatetime()) {
                    fieldValue = DateTimeUtil.dateObjectFormat(fieldValue, DateTimeUtil.DATETIME_FORMAT);
                }
                valueMap.put(name, fieldValue);
            }
        }
    }


    @Override
    public int executeUpdate(RunUpdateSqlBO updateSqlBO) {
        // 规范化更新的数据
        formatFieldValue(updateSqlBO.getUpdateFieldList(), updateSqlBO.getValueList());
        return JDBCUtil.executeUpdate(updateSqlBO);
    }

}
